package com.cn.barcode;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.util.Log;
import android.view.SurfaceHolder;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;

public class ScanManager implements SurfaceHolder.Callback {
	private SurfaceHolder holder = null;
	private Camera mCamera = null;
	public int mWidth = 0;
	public int mHeight = 0;
	private boolean mIsRelease = false;
	private Timer mTimer;
	private MyTimerTask mTimerTask;
	private OnScanOverListener mScanOverListener = null;

	private int mDstLeft = -1;
	private int mDstTop = -1;
	private int mDstWidth = -1;
	private int mDstHeight = -1;

	public ScanManager(Context context, SurfaceHolder holder) {
		this.holder = holder;
		this.holder.addCallback(this);
		this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}

	/**
	 * 将屏幕上已经显示的图像的左边距，上边距，宽，高，转换成未旋转之前的preview的对应
	 * 
	 * @param left
	 * @param top
	 * @param right
	 * @param bottom
	 * @param disPlayWidth
	 * @param disPlayHeight
	 */
	public void initalRect(int left, int top, int right, int bottom,
			int disPlayWidth, int disPlayHeight) {
		mDstLeft = top * mWidth / disPlayHeight;
		mDstTop = (disPlayWidth - right) * mHeight / disPlayWidth;

		mDstWidth = (bottom - top) * mWidth / disPlayHeight;
		mDstHeight = (right - left) * mHeight / disPlayWidth;
	}

	public void beginScan() {
		mTimer  = new Timer();
		mTimerTask = new MyTimerTask();
		mTimer.schedule(mTimerTask, 0, 1000);
	}

	@Override
	public void surfaceCreated(SurfaceHolder arg0) {


		oPenCamera(false);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
//		Camera.Parameters parameters = mCamera.getParameters();
//		// parameters.setPreviewSize(480, 320);
////		parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);   
//		mWidth = parameters.getPreviewSize().width;
//		mHeight = parameters.getPreviewSize().height;
//		parameters.setPictureFormat(PixelFormat.JPEG);
//		parameters.setJpegQuality(100);
//		mCamera.setParameters(parameters);
//		mCamera.startPreview();// 开始预览
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		Log.d("test", "surface destroy");
		stopScan();
		if( null != mCamera){
			mCamera.setPreviewCallback(null);
			mCamera.stopPreview();// 停止预览
			mCamera.release();
			mCamera = null;
		}
		
	}

	/**
	 * 自动对焦并回调Camera.PreviewCallback
	 */
	public void AutoFocusAndPreviewCallback() {
		if (mCamera == null) {
			mCamera = Camera.open();
		} else {
			mCamera.autoFocus(mAutoFocusCallBack);

		}

	}
	
	public void turnONLight(){
		stopScan();
		oPenCamera(true);
	}
	
	public void turnOffLight(){
		stopScan();
		oPenCamera(false);
	}
	
	private void oPenCamera(boolean isFlashLight){
		Log.d("test", "open camear  flash light is " + isFlashLight);
		if(mCamera != null){
			releaseCamera(mCamera);
		}
		mCamera = Camera.open();// 启动服务

		mCamera.setDisplayOrientation(90);
		try {
			mCamera.setPreviewDisplay(holder);// 设置预览

			Log.e("Camera", "surfaceCreated");
		} catch (IOException e) {
			releaseCamera(mCamera);
		}
		
		Camera.Parameters parameters = mCamera.getParameters();
		// parameters.setPreviewSize(480, 320);
		if(isFlashLight){
			parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
		}else {
			parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 
		}
		  
		mWidth = parameters.getPreviewSize().width;
		mHeight = parameters.getPreviewSize().height;
		parameters.setPictureFormat(PixelFormat.JPEG);
		parameters.setJpegQuality(100);
		mCamera.setParameters(parameters);
		mCamera.startPreview();// 开始预览
		
		beginScan();
	}

	/**
	 * 自动对焦
	 */
	private Camera.AutoFocusCallback mAutoFocusCallBack = new Camera.AutoFocusCallback() {

		@Override
		public void onAutoFocus(boolean success, Camera camera) {
			if (success && null != mCamera) { // 对焦成功，回调Camera.PreviewCallback
				mCamera.setOneShotPreviewCallback(mPreviewCallback);
			}
		}
	};

	private void releaseCamera(Camera camera) {
		mIsRelease = true;
		camera.release();
		mCamera = null;
		
	}

	class MyTimerTask extends TimerTask {
		@Override
		public void run() {
			AutoFocusAndPreviewCallback();
		}
	}
	
	public void stopScan(){
		
		if( mTimer != null){
			mTimer.cancel();
		}
		if( null != mCamera){
			mCamera.stopPreview();
			mCamera.release();
			mCamera = null;
		}
	}

	/**
	 * 自动对焦后输出图片
	 */
	private Camera.PreviewCallback mPreviewCallback = new Camera.PreviewCallback() {
		@Override
		public void onPreviewFrame(byte[] data, Camera arg1) {
			// 取得指定范围的帧的数据
			PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(
					data, mWidth, mHeight, mDstLeft, mDstTop, mDstWidth,
					mDstHeight, false);
			// 取得灰度图
			int width = source.getWidth();
			int height = source.getHeight();
			Bitmap mBitmap = Bitmap.createBitmap(width, height,
					Bitmap.Config.ARGB_8888);
			mBitmap.setPixels(source.renderCroppedGreyscaleBitmap(), 0, width,
					0, 0, width, height);
			if (mScanOverListener != null) {
				mScanOverListener.onBeforeScan(mBitmap);
			}
			BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
			MultiFormatReader reader = new MultiFormatReader();
			try {
				Result result = reader.decode(bitmap);
				String type = result.getBarcodeFormat().name();
				String text = result.getText();
				if (mScanOverListener != null) {
					mScanOverListener.onScanOver(type, text);
				}

				// mTimer.cancel();
			} catch (Exception e) {
				if (mScanOverListener != null) {
					mScanOverListener.onScanFailed();
				}
			}
		}
	};

	public void setScanOverListener(OnScanOverListener listener) {
		mScanOverListener = listener;
	}

	public static interface OnScanOverListener {
		public void onBeforeScan(Bitmap bitMap);

		public void onScanOver(String resultType, String resultText);

		public void onScanFailed();
	}

}